import re
import json
from typing import Dict, Any, Optional, Tuple
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage

class NLPTool:
    def __init__(self, llm: Optional[ChatOpenAI] = None):
        self.llm = llm
        # 定义商品类别对应的单位
        self.category_units = {
            "水果": "斤",
            "蔬菜": "斤",
            "肉类": "斤",
            "海鲜": "斤",
            "乳制品": "盒",
            "饮品": "瓶",
            "零食": "包",
            "家居用品": "件",
            "电子产品": "台",
            "运动用品": "个",
            "烘焙": "个"
        }

    def parse_purchase_intent(self, query: str) -> Dict[str, Any]:
        """解析购买意图"""
        try:
            if not self.llm:
                # 使用简单的规则解析
                items = []
                payment_method = None
                
                # 检查支付方式
                payment_methods = {
                    "现金": ["现金", "cash", "纸币"],
                    "信用卡": ["信用卡", "储蓄卡", "银行卡", "信用卡", "card"],
                    "移动支付": ["支付宝", "微信", "数字人民币", "移动支付", "扫码", "手机支付"]
                }
                
                for method, keywords in payment_methods.items():
                    if any(keyword in query.lower() for keyword in keywords):
                        payment_method = method
                        break

                # 分割多个商品
                parts = query.split('和')
                for part in parts:
                    # 使用正则表达式匹配数量和商品名
                    match = re.match(r'(\d+)([斤|个|件|包|瓶|盒]+)([^和]+)', part.strip())
                    if match:
                        quantity = float(match.group(1))
                        unit = match.group(2)
                        product_name = match.group(3).strip()
                        items.append({
                            'product_name': product_name,
                            'quantity': quantity,
                            'unit': unit
                        })

                if not items:
                    return {
                        'success': False,
                        'message': '无法解析购买意图',
                        'data': None
                    }

                return {
                    'success': True,
                    'items': items,
                    'payment_method': payment_method
                }

            # 使用 LLM 解析
            prompt = f"""
            分析以下购买请求，提取商品信息和支付方式。请严格按照指定的 JSON 格式返回结果。

            用户请求：{query}

            请返回以下格式的 JSON（不要包含任何其他文字或注释）：
            {{
                "success": true,
                "items": [
                    {{
                        "product_name": "商品名称",
                        "quantity": 数量,
                        "unit": "单位"
                    }}
                ],
                "payment_method": "支付方式"
            }}

            注意：
            1. 数量必须是数字
            2. 单位必须是：斤、个、件、包、瓶、盒 中的一个
            3. 支付方式必须是：现金、信用卡、移动支付 中的一个，如果用户未指定则返回 null
            4. 如果无法解析商品信息，返回 "success": false
            5. 返回的必须是合法的 JSON 格式
            6. 不要添加任何注释或额外说明
            """

            # 调用 LLM 并处理响应
            response = self.llm.invoke([HumanMessage(content=prompt)])
            content = response.content.strip()

            # 清理响应内容，移除所有注释和额外文字
            if "```json" in content:
                content = content.split("```json")[1].split("```")[0].strip()
            elif "```" in content:
                content = content.split("```")[1].strip()

            # 移除所有注释和空行
            content_lines = []
            for line in content.split('\n'):
                line = line.strip()
                if line and not line.startswith('//') and not line.startswith('#'):
                    content_lines.append(line)
            content = ''.join(content_lines)

            # 解析 JSON
            result = json.loads(content)

            # 验证结果格式
            if not isinstance(result, dict) or 'success' not in result or 'items' not in result:
                return {
                    'success': False,
                    'message': '解析结果格式错误',
                    'data': None
                }

            # 验证每个商品信息
            if result.get('success'):
                for item in result['items']:
                    if not all(k in item for k in ['product_name', 'quantity', 'unit']):
                        return {
                            'success': False,
                            'message': '商品信息不完整',
                            'data': None
                        }
                    # 确保数量是数字
                    item['quantity'] = float(item['quantity'])

            return result

        except json.JSONDecodeError as e:
            print(f"JSON 解析错误: {str(e)}, 原始响应: {content}")
            # 尝试使用规则解析
            return self.parse_purchase_intent(query)
        except Exception as e:
            print(f"解析购买意图时出错: {str(e)}")
            return {
                'success': False,
                'message': '解析购买意图时出错',
                'data': None
            }

    def parse_restock_intent(self, query: str) -> Dict[str, Any]:
        """解析补货意图"""
        try:
            # 匹配数量和商品名称
            patterns = [
                r"补充(\d+)([斤个瓶包盒件台])(.*)",
                r"进货(\d+)([斤个瓶包盒件台])(.*)",
                r"添加(\d+)([斤个瓶包盒件台])(.*)",
                r"补货(\d+)([斤个瓶包盒件台])(.*)",
                r"(.*)补充(\d+)([斤个瓶包盒件台])",
            ]
            
            for pattern in patterns:
                match = re.search(pattern, query)
                if match:
                    groups = match.groups()
                    if len(groups) == 3:
                        quantity = int(groups[0])
                        unit = groups[1]
                        product_name = groups[2].strip()
                        if not product_name and len(groups) > 2:
                            product_name = groups[0].strip()
                            quantity = int(groups[1])
                            unit = groups[2]
                        
                        return {
                            "type": "restock",
                            "quantity": quantity,
                            "unit": unit,
                            "product_name": product_name,
                            "explanation": f"用户想补充{quantity}{unit}{product_name}"
                        }

            return {
                "type": "unknown",
                "explanation": "无法解析补货意图"
            }

        except Exception as e:
            print(f"解析补货意图时出错: {str(e)}")
            return {
                "type": "error",
                "explanation": str(e)
            }

    def parse_payment_method(self, query: str) -> Tuple[bool, str]:
        """解析支付方式"""
        try:
            # 如果有 LLM，使用 LLM 解析
            if self.llm:
                prompt = f"""
                分析用户的支付方式选择。

                用户输入：{query}

                请判断用户选择的支付方式，并返回以下 JSON 格式的结果（不要包含其他文字）：
                {{
                    "success": true/false,
                    "payment_method": "现金/信用卡/移动支付"
                }}

                注意：
                1. 只支持：现金、信用卡、移动支付 这三种方式
                2. 如果无法确定支付方式，返回 "success": false
                """

                response = self.llm.invoke([HumanMessage(content=prompt)])
                content = response.content.strip()

                # 清理响应内容
                if "```json" in content:
                    content = content.split("```json")[1].split("```")[0].strip()
                elif "```" in content:
                    content = content.split("```")[1].strip()

                result = json.loads(content)
                if result.get("success"):
                    return True, result["payment_method"]
                return False, "未知支付方式"

            # 如果没有 LLM，使用简单的规则匹配
            payment_methods = {
                "现金": ["现金", "cash", "纸币"],
                "信用卡": ["信用卡", "储蓄卡", "银行卡", "信用卡", "card"],
                "移动支付": ["支付宝", "微信", "数字人民币", "移动支付", "扫码", "手机支付"]
            }

            query = query.lower()
            for method, keywords in payment_methods.items():
                if any(keyword in query.lower() for keyword in keywords):
                    return True, method

            return False, "未知支付方式"

        except Exception as e:
            print(f"解析支付方式时出错: {str(e)}")
            return False, "解析支付方式出错"

    def generate_response(self, intent_type: str, data: Dict[str, Any]) -> str:
        """生成响应文本"""
        if not self.llm:
            if intent_type == "purchase_success":
                if "products" in data:
                    # 多商品场景
                    products_text = "\n".join([
                        f"- {p['product_name']}: {p['quantity']}{p['unit']}，金额：{p['amount']}元"
                        for p in data['products']
                    ])
                    return f"购买成功！\n商品明细：\n{products_text}\n总金额：{data['total_amount']}元\n支付方式：{data['payment_method']}\n感谢您的购买，欢迎再次光临！"
                else:
                    # 单商品场景
                    return f"购买成功！共支付{data['amount']}元，感谢您的购买，欢迎再次光临！"
            elif intent_type == "purchase_failed":
                return f"抱歉，购买失败：{data.get('reason', '未知原因')}"
            elif intent_type == "restock_success":
                return f"补货成功！已添加{data['quantity']}{data['unit']}{data['product_name']}到库存。"
            elif intent_type == "restock_failed":
                return f"补货失败：{data.get('reason', '未知原因')}"
            return "抱歉，我不太理解您的意思。"

        try:
            if intent_type == "purchase_success":
                # 构建商品明细文本
                products_info = ""
                if "products" in data:
                    products_info = "商品明细：\n" + "\n".join([
                        f"- {p['product_name']}: {p['quantity']}{p['unit']}，金额：{p['amount']}元"
                        for p in data.get('products', [])
                    ])
                else:
                    products_info = f"- {data['product_name']}: {data['quantity']}{data['unit']}，金额：{data['amount']}元"

                prompt = f"""
                用户成功购买了商品，请生成一个友好的回复。

                购买信息：
                {products_info}
                总金额：{data.get('total_amount', data.get('amount'))}元
                支付方式：{data['payment_method']}

                要求：
                1. 确认购买成功
                2. 列出商品明细
                3. 说明总金额
                4. 表达感谢
                5. 欢迎再次光临
                6. 语气要温暖友好
                """
            elif intent_type == "purchase_failed":
                prompt = f"""
                用户购买失败，请生成一个友好的回复。

                失败信息：
                - 商品：{data['product_name']}
                - 数量：{data['quantity']}{data['unit']}
                - 失败原因：{data.get('reason', '未知原因')}

                要求：
                1. 表达歉意
                2. 说明失败原因
                3. 如果是库存不足，告知当前库存量
                4. 给出建设性建议
                5. 语气要诚恳
                """
            elif intent_type == "restock_success":
                prompt = f"""
                成功补充了商品库存，请生成一个确认回复。

                补货信息：
                - 商品：{data['product_name']}
                - 补充数量：{data['quantity']}{data['unit']}
                - 当前库存：{data.get('current_stock', '未知')}

                要求：
                1. 确认补货成功
                2. 说明补充数量
                3. 如果有当前库存信息，一并告知
                4. 语气要专业
                """
            elif intent_type == "restock_failed":
                prompt = f"""
                补充库存失败，请生成一个解释性回复。

                失败信息：
                - 商品：{data['product_name']}
                - 计划补充数量：{data['quantity']}{data['unit']}
                - 失败原因：{data.get('reason', '未知原因')}

                要求：
                1. 说明失败原因
                2. 给出改进建议
                3. 语气要专业且有建设性
                """
            else:
                return "抱歉，我不太理解您的意思。"

            response = self.llm.invoke([HumanMessage(content=prompt)])
            return response.content

        except Exception as e:
            print(f"生成响应文本时出错: {str(e)}")
            return "抱歉，生成响应时出现错误。" 